<script setup lang="ts">
import { type Ref, ref } from 'vue'
import { createDiscreteApi } from 'naive-ui'
import LoginApi from '@/api/modules/LoginApi';

const { message } = createDiscreteApi(['message'])

// 获取授权确认信息响应
const consentResult: Ref<any> = ref()
// 所有的scope
const scopes = ref()
// 已授权的scope
const approvedScopes = ref()
// 提交/拒绝按钮加载状态
const loading = ref(false)

/**
 * 初始化需要授权确认的客户端与scope
 */

console.log(window.location.search);
LoginApi.getConsentParameters(window.location.search)
  .then((res: any) => {
    console.log(res);
    res = res.data
    if (res.success) {
      consentResult.value = res.data
      scopes.value = [...res.data.previouslyApprovedScopes, ...res.data.scopes]
      approvedScopes.value = res.data.previouslyApprovedScopes.map((e: any) => e.scope)
    } else {
      message.warning(res.message)
    }
  })
  .catch((e: any) => {
    message.warning(`获取客户端与scope信息失败：${e.message || e.statusText}`)
  })

/**
 * 提交授权确认
 *
 * @param cancel true为取消
 */
const submitApprove = (cancel: boolean) => {
  console.log(consentResult.value);

  if (!consentResult.value) {
    message.warning(`初始化未完成，无法提交`)
    return
  }
  loading.value = true
  const data = new FormData()
  if (!cancel) {
    // 如果不是取消添加scope
    if (
      approvedScopes.value !== null &&
      typeof approvedScopes.value !== 'undefined' &&
      approvedScopes.value.length > 0
    ) {
      approvedScopes.value.forEach((e: any) => data.append('scope', e))
    }
  }
  data.append('state', consentResult.value.state)
  data.append('client_id', consentResult.value.clientId)
  data.append('user_code', consentResult.value.userCode)
  console.log(consentResult.value.requestURI)
  LoginApi.submitApproveScope(
    // @ts-ignore
    new URLSearchParams(data),
    consentResult.value.requestURI
  )
    .then((result: any) => {
      result = result.data
      if (result.success) {
        window.location.href = result.data
      } else {
        if (result.message && result.message.indexOf('access_denied') > -1) {
          // 可以跳转至一个单独的页面提醒.
          message.warning('您未选择scope或拒绝了本次授权申请.')
        } else {
          message.warning(result.message)
        }
      }
    })
    .catch((e: any) => {
      message.warning(`提交授权确认失败：${e.message || e.statusText}`)
    })
    .finally(() => (loading.value = false))
}
</script>

<template>
  <div class="container">
    <n-card v-if="consentResult && consentResult.userCode" class="info-card">
      <p>您已经提供了代码 <b>{{ consentResult.userCode }}</b>，请验证此代码是否与设备上显示的代码匹配。</p>
    </n-card>
    
    <n-card v-if="consentResult" :title="`客户端 ${consentResult.clientName}`" class="consent-card">
      <div class="consent-details">
        <p>账号：<b>{{ consentResult.principalName }}</b></p>
        <p>此第三方应用请求获得以下权限：</p>
      </div>
      
      <n-scrollbar class="scopes-scrollbar">
        <n-checkbox-group v-model:value="approvedScopes">
          <n-list>
            <n-list-item v-for="scope in scopes" :key="scope" class="scope-item">
              <template #prefix>
                <n-checkbox :value="scope.scope"></n-checkbox>
              </template>
              <n-thing :title="scope.scope" :description="scope.description" />
            </n-list-item>
          </n-list>
        </n-checkbox-group>
      </n-scrollbar>
    </n-card>
    
    <div class="buttons">
      <n-button type="info" :loading="loading" @click="submitApprove(false)" strong>确定</n-button>
      <n-button type="warning" :loading="loading" @click="submitApprove(true)">拒绝</n-button>
    </div>
  </div>
</template>

<style scoped>
.container {
  padding: 2rem;
  max-width: 600px;
  min-width: 450px;
  margin: 0 auto;
  font-family: 'Helvetica Neue', Arial, sans-serif;
  color: #333;
}

.info-card, .consent-card {
  margin-bottom: 1rem;
}

.info-card {
  background-color: #f0f8ff;
  border-color: #b0c4de;
}

.consent-card {
  background-color: #fff8dc;
  border-color: #f5deb3;
}

.consent-details {
  margin-bottom: 1rem;
}

.scopes-scrollbar {
  max-height: 230px;
  background-color: #fafafa;
  margin-bottom: 1rem;
}

.scope-item {
  display: flex;
  align-items: center;
  margin-left: 30px;
}

.buttons {
  display: flex;
  justify-content: space-between;
}

@media (min-width: 768px) {
  .container {
    padding: 3rem;
  }
}
</style>
